#include <string>
#include <iostream>
#include <fstream>
#include "cJSON.h"
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstdlib>

int main() {
    std::ofstream fout_errors, fout_warmings, fout_infos;
    fout_errors.open("home\\easy\\data\\edge\\errors.log", std::ios_base::out | std::ios_base::app);
    fout_warmings.open("home\\easy\\data\\edge\\warmings.log", std::ios_base::out | std::ios_base::app);
    fout_infos.open("home\\easy\\data\\edge\\infos.log", std::ios_base::out | std::ios_base::app);

    //创建请求令牌的json文件
    cJSON *root_request=cJSON_CreateObject();
    std::cout<<"into name"<<std::endl;
    char *name;
    std::cin>>name;
    std::cout<<"into password"<<std::endl;
    char *password;
    std::cin>>password;
    cJSON_AddNumberToObject(root_request, "code", 1);
    cJSON_AddStringToObject(root_request,"name",name);
    cJSON_AddStringToObject(root_request,"password",password);
    char *request;
    request= cJSON_Print(root_request);
    cJSON_Delete(root_request);
    //创建应答令牌的字符串
    char *response;

    //判断文件是否打开成功
    if ((fout_errors.is_open()) && (fout_warmings.is_open()) && (fout_infos.is_open())) {
        //若成功打开文件，向数据存储子系统获取令牌
        int client_fd, server_fd;
        struct sockaddr_in server_addr;
        struct sockaddr_in client_addr;
        socklen_t client_addr_len;
        //建立一个接口
        server_fd = socket(PF_INET, SOCK_DGRAM, 0);
        if (server_fd == -1) {
            perror("socket:");
            exit(1);
        }
        //初始化服务端信息
        server_addr.sin_family = AF_INET;
        server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        server_addr.sin_port = htons(9090);
        //初始化客户端信息
        client_addr.sin_addr.s_addr = inet_addr("192.168.1.202");
        client_addr.sin_port = htons(9090);
        //绑定端口和地址
        if (bind(server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) == -1) {
            perror("bind:");
            exit(1);
        }
        //向数据存储系统发送边缘令牌
        client_addr_len = sizeof(client_addr_len);

        sendto(server_fd, &request, sizeof(request), 0,
               (struct sockaddr *) &client_addr, client_addr_len);
        //接受应答令牌
        client_addr_len = sizeof(client_addr);
        int r = recvfrom(server_fd, &response, sizeof(response), 0,
                         (struct sockaddr *) &client_addr, &client_addr_len);
        response[sizeof (response)]=0;
        if (r == -1) exit(1);
        else {
            //对消息队列发送“成功”事件

            //创建一个保存令牌的文件,便于后面使用
            std::ofstream file_token;
            file_token.open("token.txt");
            std::string str=response;
            file_token<<str;
            file_token.close();
            //创建用于记录本次启动运行日期时间的文件
            std::ofstream fout_lastren;
            fout_lastren.open("lastrun.txt", std::ios_base::out | std::ios_base::app);
            if (fout_lastren.is_open()) {
                time_t t;
                time(&t);
                fout_lastren << ctime(&t);
                fout_lastren.close();
            } else {
                //若失败，向消息队列发送“失败”事件，失败原因和等级

                return -1;
            }
       }

        fout_errors.close();
        fout_warmings.close();
        fout_infos.close();
        return 0;
    }
}